/**
 * Copyright (c) 2008 Matthew E. Kimmel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package net.kleinhenz.quendor.zmachine;

import java.util.Vector;

/**
 * ZUserInterface - This interface must be implemented by a programmer
 * using the ZMachine classes, to provide various I/O routines and
 * other routines that will differ with different user interfaces.
 *
 * @author Matt Kimmel
 */
public interface ZUserInterface {

	public static final int STYLE_ROMAN = 0;
	public static final int STYLE_REVERSE = 1;
	public static final int STYLE_BOLD = 2;
	public static final int STYLE_ITALICS = 4;
	public static final int STYLE_FIXED = 8;
	
	public static final int FONT_NORMAL = 1;
	public static final int FONT_PICTURE = 2;
	public static final int FONT_CHARGRAPHICS = 3;
	public static final int FONT_FIXED = 4;

	public static final int COLOR_CURRENT = 0;
	public static final int COLOR_DEFAULT = 1;
	public static final int COLOR_BLACK = 2;
	public static final int COLOR_RED = 3;
	public static final int COLOR_GREEN = 4;
	public static final int COLOR_YELLOW = 5;
	public static final int COLOR_BLUE = 6;
	public static final int COLOR_MAGENTA = 7;
	public static final int COLOR_CYAN = 8;
	public static final int COLOR_WHITE = 9;
	public static final int COLOR_LIGHTGREY = 10;
	public static final int COLOR_MEDIUMGREY = 11;
	public static final int COLOR_DARKGREY = 12;

	/**
	 * This method is called when a fatal error is encountered.
     * It should never return.
     * 
	 * @param errmsg
	 */
    public void fatal(String errmsg);

    /**
     * This method is called when the game starts or restarts,
     * to initialize windows and such.  The version number of
     * the current game is passed.
     * 
     * @param version
     */
    public void initialize(int ver);

    /**
     * This method sets the additional terminating characters for
     * READ operations.  It should be called after initialize, and
     * should be passed a Vector of Integer objects containing
     * the Z-Characters that should be treated as terminating characters.
     * 
     * @param chars
     */
    public void setTerminatingCharacters(Vector<Integer> chars);
    
    /**
     * This method returns true if the user interface supports a status line.
     * 
     * @return
     */
    public boolean hasStatusLine();

    /**
     * This method returns true if the user interface supports an upper window.
     * 
     * @return
     */
    public boolean hasUpperWindow();

    /**
     * This method returns true if the default font is variable-width.
     *  
     * @return
     */
    public boolean defaultFontProportional();

	/**
	 * This method returns true if the user interface supports colors.
	 * 
	 * @return
	 */
	public boolean hasColors();

	/**
	 * This method returns true if boldface styles are available.
	 * 
	 * @return
	 */
	public boolean hasBoldface();

	/**
	 * This method returns true if italic styles are available.
	 * 
	 * @return
	 */
	public boolean hasItalic();

	/**
	 * This method returns true if fixed-width styles are available.
	 * 
	 * @return
	 */
	public boolean hasFixedWidth();

    /**
     * This method returns true if timed input is supported.
     * 
     * @return
     */
    public boolean hasTimedInput();
    
	/**
	 * This method returns the size of the "screen" in lines/columns.
	 * 
	 * @return
	 */
	public Dimension getScreenCharacters();

	/**
	 * This method returns the size of the "screen" in "units".
	 * 
	 * @return
	 */
	public Dimension getScreenUnits();

	/**
	 * This method returns the size of the current font in "units".
	 * 
	 * @return
	 */
	public Dimension getFontSize();

    /**
     * This method returns the size of the specified window, in characters.
     * 
     * @param window
     * @return
     */
    public Dimension getWindowSize(int window);
    
	/**
	 * This method return the default foreground color (as Z-Machine color numbers):
	 *  -1 =  the colour of the pixel under the cursor (if any)
	 *  0  =  the current setting of this colour
     *  1  =  the default setting of this colour
     *  2  =  black   3 = red       4 = green    5 = yellow
     *  6  =  blue    7 = magenta   8 = cyan     9 = white
     * 10 =  darkish grey (MSDOS interpreter number)
     * 10 =  light grey   (Amiga interpreter number)
     * 11 =  medium grey  (ditto)
     * 12 =  dark grey    (ditto)
     * 
	 * @return
	 */
	public int getDefaultForeground();
	
	/**
	 * This method return the default foreground color (as Z-Machine color numbers):
	 *  -1 =  the colour of the pixel under the cursor (if any)
	 *  0  =  the current setting of this colour
     *  1  =  the default setting of this colour
     *  2  =  black   3 = red       4 = green    5 = yellow
     *  6  =  blue    7 = magenta   8 = cyan     9 = white
     * 10 =  darkish grey (MSDOS interpreter number)
     * 10 =  light grey   (Amiga interpreter number)
     * 11 =  medium grey  (ditto)
     * 12 =  dark grey    (ditto)
     * 
	 * @return
	 */
	public int getDefaultBackground();

	/**
	 * This method returns the current cursor position.
	 * 
	 * @return
	 */
	public Point getCursorPosition();

    /**
     * This method shows the status bar.  This is handled entirely by the user interface, 
     * rather than in the CPU or the I/O card, in order to give the user interface programmer 
     * some flexibility about where to put the information (in the window title bar, for example).
     */
    public void showStatusBar(String s,int a,int b,boolean flag);

    /**
     * Split the screen, as per SPLIT_SCREEN instruction
     * 
     * @param lines
     */
    public void splitScreen(int lines);
    
    /**
     * This method sets the current window, to which all output will be directed.  In V1-3, this 
     * implies clearing the window; in V4+, it implies homing the cursor.
     * 
     * @param window
     */
    public void setCurrentWindow(int window);

	/**
	 * This method sets the cursor to position x,y (or turns the cursor on or off -- see Z-Machine spec).
	 * 
	 * @param x
	 * @param y
	 */
	public void setCursorPosition(int x,int y);

	/**
	 * This method sets the foreground and background colors. 0 means no change.
	 * 
	 * @param fg
	 * @param bg
	 */
	public void setColor(int fg,int bg);

	/**
	 * Set the text style (see Z-Machine spec for meaning of parameter):
	 * Roman (if 0), Reverse Video (if 1), Bold (if 2), Italic (4), Fixed Pitch (8)
	 * 
	 * @param style
	 */
	public void setTextStyle(int style);

	/**
	 * Set the font--again, see Z-Spec:
	 * 1: the normal font
     * 2: a picture font
     * 3: a character graphics font
     * 4: a Courier-style font with fixed pitch
	 * 
	 * @param font
	 */
	public void setFont(int font);

    /**
     * This method reads a line of user input and appends it to the supplied StringBuffer; it returns the 
     * terminating character. If time is nonzero, the readLine will time out if a terminating character 
     * has not been encountered after time tenths of a second. If a timeout occurs, the return value will be 0.
     * 
     * @param sb
     * @param time
     * @return
     */
	public int readLine(StringBuffer sb,int time);

    /**
     * This method reads a character from the user and returns it.  If time is nonzero, 
     * it times out after time/10 seconds.
     * 
     * @param time
     * @return
     */
    public int readChar(int time);

    /**
     * Print a string
     * 
     * @param s
     */
    public void showString(String s);

    /**
     * This method scrolls the current window by the specified number of lines.
     * 
     * @param lines
     */
    public void scrollWindow(int lines);

    /**
     * This method erases a line in the current window.
     * 
     * @param s
     */
    public void eraseLine(int s);

	/**
	 * This method erases the current window.
	 * 
	 * @param window
	 */
	public void eraseWindow(int window);

	/**
	 * This method gets a filename from the user, possibly using a FileDialog. A title for a dialog box is supplied.  
	 * If saveFlag is true, then we are saving a file; otherwise, we're loading a file. The method should return 
	 * null if there was an error or the user canceled.
	 * 
	 * @param title
	 * @param suggested
	 * @param saveFlag
	 * @return
	 */
	public String getFilename(String title,String suggested,boolean saveFlag);

    /**
     * This function is called when the Z-Machine halts. It should not return.
     */
    public void quit();

	/**
	 * This function is called when the Z-Machine is about to restart.  The UI should prepare by 
	 * reseting itself to an initial state. The function should return.
	 */
	public void restart();
}
